/*
 * Copyright (c) 2012 Johan Fylling
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 * THE SOFTWARE.
 */

part of engine;


class DynamicBody extends SmartElement {
  static int           _idBase             = 1;
  int                  _id                 = 0;
  
  static int           activityCounterBase = 100;
  int                  activityCounter     = activityCounterBase;
  
  static final Vector2 baseOrientation     = new Vector2(0,1);
  Vector2              position            = new Vector2(0.0, 0.0);
  num                  angle               = 0.0;
  Vector2              velocity            = new Vector2(0.0, 0.0);
  num                  mass                = 0.0;
  
  Collidable           collidable          = null;
  var                  data                = null;
  
  DynamicBody ([var data]) : _id = ++_idBase;
  
  bool get active => this.activityCounter > 0;
  
  int get id => this._id;
  
  String toString () => "[$_id $position:$angle:$mass]";
  
  toJson () {
    return {
      "type": "dynamic_body",
      "id": _id,
      "position": position,
      "angle": angle,
      "velocity": velocity,
      "mass": mass,
      "collidable": collidable
    };
  }
}


class DynamicBodyStorageHandler {
  call (StorageManager manager, Map attributes) {
    DynamicBody body = new DynamicBody();
    
    var collidableAttributes = attributes["collidable"];
    assert(collidableAttributes is Map);
    var collidable = manager.load(collidableAttributes);
    assert(collidable is Collidable);
    body.collidable = collidable;
    
    setAttributes(manager, attributes, body);
    return body;
  }
  
  void setAttributes (StorageManager manager, Map attributes, DynamicBody body) {
    var positionAttributes = attributes["position"];
    assert(positionAttributes is Map);
    Vector2 position = new Vector2(positionAttributes["x"], positionAttributes["y"]);
    body.position = position;
    
    var angle = attributes["angle"];
    if (angle != null) {
      assert(angle is num);
      body.angle = angle;
    }
    
    var velocityAttributes = attributes["velocity"];
    if (velocityAttributes != null) {
      assert(velocityAttributes is Map);
      Vector2 velocity = new Vector2(velocityAttributes["x"], velocityAttributes["y"]);
      body.velocity = velocity;
    }
    
    var mass = attributes["mass"];
    if (mass != null) {
      assert(mass is num);
      body.mass = mass;
    }
  }
}
